package com.uniknow.app.widget.pullview;

import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Scroller;

/**
 * 类名称：PullListView   
 * 类描述：    下拉（上滑）刷新（加载）列表
 * @创建者：zhangyao     
 * @创建时间：2014年6月12日
 * @变更记录：2014年6月12日上午9:38:32 by 记录变更人
 */
public class PullListView extends ListView implements OnScrollListener {

	/** The m last y. */
	private float mLastY = -1;
	
	/** The m scroller. */
	private Scroller mScroller; 
	
	/** The m scroll listener. */
	private OnScrollListener mScrollListener; 

	/** The m list view listener. */
	private OnListViewListener mListViewListener;

	/** The m header view. */
	private ListViewHeader mHeaderView;
	
	/** The m footer view. */
	private ListViewFooter mFooterView;
	
	/** The m header view height. */
	private int mHeaderViewHeight; 
	
	/** The m footer view height. */
	private int mFooterViewHeight; 
	
	/** The m enable pull refresh. */
	private boolean mEnablePullRefresh = true;
	
	/** The m enable pull load. */
	private boolean mEnablePullLoad = true;
	
	/** The m pull refreshing. */
	private boolean mPullRefreshing = false;
	
	/** The m pull loading. */
	private boolean mPullLoading;

	/** The m is footer ready. */
	private boolean mIsFooterReady = false;

	// total list items, used to detect is at the bottom of listview.
	/** The m total item count. */
	private int mTotalItemCount;

	// for mScroller, scroll back from header or footer.
	/** The m scroll back. */
	private int mScrollBack;
	
	/** The Constant SCROLLBACK_HEADER. */
	private final static int SCROLLBACK_HEADER = 0;
	
	/** The Constant SCROLLBACK_FOOTER. */
	private final static int SCROLLBACK_FOOTER = 1;

	/** The Constant SCROLL_DURATION. */
	private final static int SCROLL_DURATION = 200;
	
	/** The Constant OFFSET_RADIO. */
	private final static float OFFSET_RADIO = 1.8f; 
	
	/** 数据相关. */
	private ListAdapter mAdapter = null;
	
	/**
	 * Instantiates a new ab pull list view.
	 *
	 * @param context the context
	 */
	public PullListView(Context context) {
		super(context);
		initWithContext(context);
	}

	/**
	 * Instantiates a new ab pull list view.
	 *
	 * @param context the context
	 * @param attrs the attrs
	 */
	public PullListView(Context context, AttributeSet attrs) {
		super(context, attrs);
		initWithContext(context);
	}

	/**
	 * Inits the with context.
	 *
	 * @param context the context
	 */
	private void initWithContext(Context context) {
		
		mScroller = new Scroller(context, new DecelerateInterpolator());
		
		super.setOnScrollListener(this);

		// init header view
		mHeaderView = new ListViewHeader(context);
		
		// init header height
		mHeaderViewHeight = mHeaderView.getHeaderHeight();
		mHeaderView.setGravity(Gravity.BOTTOM);
		addHeaderView(mHeaderView);

		// init footer view
		mFooterView = new ListViewFooter(context);
		
		mFooterViewHeight= mFooterView.getFooterHeight();
		mFooterView.hide();
		//默认是打开刷新与更多
		setPullRefreshEnable(true);
		setPullLoadEnable(true);
	}

	/**
	 * 描述：TODO
	 * @see android.widget.ListView#setAdapter(android.widget.ListAdapter)
	 * @version v1.0
	 */
	@Override
	public void setAdapter(ListAdapter adapter) {
		mAdapter = adapter;
		// make sure XListViewFooter is the last footer view, and only add once.
		if (mIsFooterReady == false) {
			mIsFooterReady = true;
			mFooterView.setGravity(Gravity.TOP);
			addFooterView(mFooterView);
		}
		super.setAdapter(adapter);
	}

	/**
	 * 打开或者关闭下拉刷新功能.
	 *
	 * @param enable 开关标记
	 */
	public void setPullRefreshEnable(boolean enable) {
		mEnablePullRefresh = enable;
		if (!mEnablePullRefresh) {
			mHeaderView.setVisibility(View.INVISIBLE);
		} else {
			mHeaderView.setVisibility(View.VISIBLE);
		}
	}

	/**
	 * 打开或者关闭加载更多功能.
	 *
	 * @param enable 开关标记
	 */
	public void setPullLoadEnable(boolean enable) {
		mEnablePullLoad = enable;
		if (!mEnablePullLoad) {
			mFooterView.hide();
			mFooterView.setOnClickListener(null);
		} else {
			mPullLoading = false;
			mFooterView.setState(ListViewFooter.STATE_READY);
			//load more点击事件.
			mFooterView.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					startLoadMore();
				}
			});
		}
	}

	/**
	 * stop refresh, reset header view.
	 */
	public void stopRefresh() {
		if (mPullRefreshing == true) {
			mPullRefreshing = false;
			resetHeaderHeight();
		}
		
		int count = mAdapter.getCount();
		//判断有没有数据
		if(count>0){
			mFooterView.setState(ListViewFooter.STATE_READY);
		}else{
			mFooterView.setState(ListViewFooter.STATE_EMPTY);
		}
	}

	/**
	 * stop load more, reset footer view.
	 *
	 * @param more the more
	 */
	public void stopLoadMore(boolean more) {
		if (mPullLoading == true) {
			mPullLoading = false;
			mFooterView.setState(ListViewFooter.STATE_READY);
		}
		//判断有没有更多数据了
		if(more){
			mFooterView.setState(ListViewFooter.STATE_READY);
		}else{
			mFooterView.setState(ListViewFooter.STATE_NO);
		}
		
		toScrollHideFooter();
	}



	/**
	 * Update header height.
	 *
	 * @param delta the delta
	 */
	private void updateHeaderHeight(float delta) {
		int newHeight = (int) delta + mHeaderView.getVisiableHeight();
		mHeaderView.setVisiableHeight(newHeight);
		if (mEnablePullRefresh && !mPullRefreshing) {
			if (mHeaderView.getVisiableHeight() >= mHeaderViewHeight) {
				mHeaderView.setState(ListViewHeader.STATE_READY);
			} else {
				mHeaderView.setState(ListViewHeader.STATE_NORMAL);
			}
		}
		setSelection(0); 
	}

	/**
	 * 根据状态设置Header的位置.
	 */
	private void resetHeaderHeight() {
		//当前下拉到的高度
		int height = mHeaderView.getVisiableHeight();
		if (height < mHeaderViewHeight || !mPullRefreshing) {
			//距离短  隐藏
			mScrollBack = SCROLLBACK_HEADER;
			mScroller.startScroll(0, height, 0, -1*height, SCROLL_DURATION);
		}else if(height > mHeaderViewHeight || !mPullRefreshing){
			//距离多的  弹回到mHeaderViewHeight
			mScrollBack = SCROLLBACK_HEADER;
			mScroller.startScroll(0, height, 0, -(height-mHeaderViewHeight), SCROLL_DURATION);
		}
		
		invalidate();
	}
	
	/**
	 * 将 底部加载view隐藏
	 */
	private void toScrollHideFooter(){
		if (getLastVisiblePosition() == mTotalItemCount-1) {
			int height = mFooterView.getVisiableHeight();
			if (!mPullLoading) {
				//距离短  隐藏
				mScrollBack = SCROLLBACK_FOOTER;
				mScroller.startScroll(0, 0, 0, height, SCROLL_DURATION);
			}
		}else{
			mFooterView.hide();	
		}
		
	}

	/**
	 * 更新 footer的显示.
	 * @param delta 增加值
	 */
	private void updateFooterHeight(float delta) {
		int newHeight = mFooterView.getVisiableHeight() + (int) delta;
		if(newHeight > mFooterViewHeight){
			newHeight = mFooterViewHeight;
		}
		mFooterView.setVisiableHeight(newHeight);
		if (mEnablePullLoad && !mPullLoading) {
			if (newHeight >= mFooterViewHeight) {
				mFooterView.setState(ListViewFooter.STATE_READY);
			}
		}
	}

	/**
	 * Start load more.
	 */
	private void startLoadMore() {
		if(mPullLoading)
			return;
		
		mPullLoading = true;
		mFooterView.setState(ListViewFooter.STATE_LOADING);
		if (mListViewListener != null) {
			//开始下载数据
			mListViewListener.onLoadMore();
		}
	}

	/**
	 * 描述：TODO
	 * @see android.widget.ListView#onTouchEvent(android.view.MotionEvent)
	 * @author: zhaoqp
	 * @date：2013-9-4 下午4:06:32
	 * @version v1.0
	 */
	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		if (mLastY == -1) {
			mLastY = ev.getRawY();
		}

		switch (ev.getAction()) {
		case MotionEvent.ACTION_DOWN:
			mLastY = ev.getRawY();
			break;
		case MotionEvent.ACTION_MOVE:
			final float deltaY = ev.getRawY() - mLastY;
			mLastY = ev.getRawY();
			if (getFirstVisiblePosition() == 0 && (mHeaderView.getVisiableHeight() > 0 || deltaY > 0)) {
				updateHeaderHeight(deltaY / OFFSET_RADIO);
			} else if (mEnablePullLoad && getLastVisiblePosition() == mTotalItemCount - 1 && mFooterView.getVisiableHeight() < mFooterViewHeight) {
				updateFooterHeight(-deltaY / OFFSET_RADIO);
			}
			break;
		case MotionEvent.ACTION_UP:
			mLastY = -1; 
			if (getFirstVisiblePosition() == 0) {
				//需要刷新的条件
				if (mEnablePullRefresh && mHeaderView.getVisiableHeight() >= mHeaderViewHeight) {
					if(!mPullRefreshing){
						mPullRefreshing = true;
						mHeaderView.setState(ListViewHeader.STATE_REFRESHING);
						if (mListViewListener != null) {
							//刷新
							mListViewListener.onRefresh();
						}
					}					
				}
				
				if(mEnablePullRefresh){
					//弹回
					resetHeaderHeight();
				}
				
				/*if(mFooterView.getVisiableHeight() >0 && mFooterView.getVisiableHeight() < mFooterViewHeight-2){					
					toScrollHideFooter();
				}else if (mEnablePullLoad && mFooterView.getVisiableHeight() > mFooterViewHeight-2){
					startLoadMore();
				}*/
				
			} else if (getLastVisiblePosition() == mTotalItemCount-1) {
				if (mEnablePullLoad && mFooterView.getVisiableHeight() > mFooterViewHeight-2) {
					startLoadMore();
				}/*else{
					toScrollHideFooter();
				}*/
			}
			break;
		default:
			break;
		}
		return super.onTouchEvent(ev);
	}

	/**
	 * 描述：TODO
	 * @see android.view.View#computeScroll()
	 */
	@Override
	public void computeScroll() {
		if (mScroller.computeScrollOffset()) {
			if (mScrollBack == SCROLLBACK_HEADER) {
				mHeaderView.setVisiableHeight(mScroller.getCurrY());
			}else if(mScrollBack == SCROLLBACK_FOOTER){
				mFooterView.setVisiableHeight(mFooterViewHeight - mScroller.getCurrY());
			}
			postInvalidate();
		}
		super.computeScroll();
	}

	/**
	 * 描述：设置ListView的监听器.
	 *
	 * @param listViewListener the new ab on list view listener
	 */
	public void setOnListViewListener(OnListViewListener listViewListener) {
		mListViewListener = listViewListener;
	}

	/**
	 * 描述：TODO
	 * @see android.widget.AbsListView.OnScrollListener#onScrollStateChanged(android.widget.AbsListView, int)
	 * @author: 
	 * @version v1.0
	 */
	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		if (mScrollListener != null) {
			mScrollListener.onScrollStateChanged(view, scrollState);
		}
	}

	/**
	 * 描述：TODO
	 * @see android.widget.AbsListView.OnScrollListener#onScroll(android.widget.AbsListView, int, int, int)
	 */
	@Override
	public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
		// send to user's listener
		mTotalItemCount = totalItemCount;
		if (mScrollListener != null) {
			mScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
		}	
	}

	/**
	 * 
	 * 描述：获取Header View
	 * @return
	 * @throws 
	 */
	public ListViewHeader getHeaderView() {
		return mHeaderView;
	}

	/**
	 * 
	 * 描述：获取Footer View
	 * @return
	 * @throws 
	 */
	public ListViewFooter getFooterView() {
		return mFooterView;
	}
	
	/**
	 * 
	 * 描述：获取Header ProgressBar，用于设置自定义样式
	 * @return
	 * @throws 
	 */
	public ProgressBar getHeaderProgressBar() {
		return mHeaderView.getHeaderProgressBar();
	}
	
	
	/**
	 * 
	 * 描述：获取Footer ProgressBar，用于设置自定义样式
	 * @return
	 * @throws 
	 */
	public ProgressBar getFooterProgressBar() {
		return mFooterView.getFooterProgressBar();
	}
	
	
}
